<script setup lang="ts">
defineOptions({
  // name 作为一种规范最好必须写上并且和路由的name保持一致
  name: "Role"
});
import { ref, reactive, toRaw } from "vue";
import { Calendar, Search } from "@element-plus/icons-vue";
import { itemList, addItem, delItem, mneuList } from "@/api/roles";
import { type DataInfo, setToken, removeToken } from "@/utils/auth";
import { json } from "stream/consumers";
import { func } from "vue-types";
import { addDialog } from "@/components/ReDialog";
import type { FormInstance, FormRules } from "element-plus";
import { ElMessage } from "element-plus";
import { ElNotification } from "element-plus";

import { ElTree } from "element-plus";
import type Node from "element-plus/es/components/tree/src/model/node";
import { log } from "node:console";
import { nextTick } from "process";
const mneudata = ref([]);
const folderTreeRef = ref(null);
// 树形菜单函数
function GetTreeData(data) {
  let TreeData = [];
  let map = new Map(); //存在id,对应所在的内存地址
  // console.log(map);
  let outputObj, pid;
  for (let i = 0; i < data.length; i++) {
    pid = data[i].pid;
    if (map.has(pid)) {
      //存在，将些信息，加入到对应id=pid的对象上的children
      if (!map.get(pid).children) map.get(pid).children = [];
      let obj = new Object(data[i]);
      map.get(pid).children.push(obj);
      map.set(data[i].id, obj);
      // console.log(map);
    } else if (!map.has(pid) && pid == 0) {
      //这里处理pid不存在，且pid 为0的处理，pid不存在，且不为0的，程序不考虑这种情况
      outputObj = new Object(data[i]);
      TreeData.push(outputObj);
      map.set(data[i].id, outputObj);
      // console.log(map);
    }
  }
  return TreeData;
  console.log(map);
}
// 菜单列表请求
const tableData = ref([]);

function valtra() {
  new Promise((resolve, reject) => {
    mneuList()
      .then(data => {
        mneudata.value = GetTreeData(JSON.parse(data).data);
        console.log(mneudata.value);
      })
      .catch(error => {
        console.log(error);
      });
  });
}
valtra();
renders();
function renders() {
  new Promise((resolve, reject) => {
    itemList()
      .then(data => {
        tableData.value = JSON.parse(data).data;
        console.log(tableData.value);
        tableDatalen.value = tableData.value.length;
      })
      .catch(error => {
        reject(error);
      });
  });
}
// 菜单选项
const mneuName = ref("");
const status = ref();

const form = reactive({
  name: "",
  type: "",
  menus: []
});
function clearVal() {
  form.type = "";
  form.name = "";
  form.menus = [];
}
let chongzhi = () => {
  clearVal();
  loading.value = true;
  setTimeout(() => {
    loading.value = false;
  }, 800);
  renders();
  mneuName.value = "";
  status.value = "";
};
let addon = () => {
  clearVal();
  dialogFormVisible.value = true;
  opstatus.value = 1;
  console.log(opstatus.value);
  folderTreeRef.value?.setCheckedNodes([]);
  checkstatus.value = 0;
};
const dialogFormVisible = ref(false);
const formLabelWidth = "140px";
const modelTitle = ref("添加菜单");
// 表单校验

const ruleFormRef = ref(null);
const rules = ref({
  name: [{ required: true, message: "请完善角色名称", trigger: "blur" }],
  type: [{ required: true, message: "请完善角色类型", trigger: "change" }]
});

// 添加/编辑状态
const opstatus = ref(0);
// 编辑按钮
const efitid = ref();
function showinfo(data) {
  for (let item of data) {
    if (item.id == efitid.value) {
      form.name = item.name;
      form.type = `${item.type}`;
      form.menus = item.menus.split(",");
    }
  }
}
let aaa = [];
let treearr = [];
function treemneus(mneudatas) {
  for (let item of mneudatas) {
    if (item.children) {
      treearr.forEach(element => {
        if (element == item.id) {
          aaa.push(item);
        }
      });
    } else {
      treearr.forEach(element => {
        if (element == item.id) {
          aaa.push(item);
        }
      });
    }
  }
  return;
}

let editbox = edid => {
  console.log(mneudata.value);
  aaa = [];
  treearr = [];
  clearVal();
  dialogFormVisible.value = true;
  efitid.value = edid;
  opstatus.value = 2;
  showinfo(tableData.value);
  for (let item of form.menus) {
    treearr.push(parseInt(item));
  }
  treemneus(mneudata.value);
  console.log(GetTreeData(aaa));
  nextTick(() => {
    folderTreeRef.value?.setCheckedNodes(GetTreeData(aaa));
  })
  
  console.log(opstatus.value);
  console.log(form);
};
// 菜单添加
let addMneu = () => {
  console.log(ruleFormRef.value);
  console.log(form);

  ruleFormRef.value.validate(valid => {
    console.log(valid);

    // 不通过校验
    if (!valid) return ElMessage.error("请将内容填写完成后 再进行添加操作!");
    if (opstatus.value == 1) {
      if (form.menus.length > 0) {
        let addobj = {
          type: form.type,
          name: form.name,
          menus: form.menus.join(",")
        };
        addItem(addobj)
          .then(data => {
            console.log(JSON.parse(data));
            if (JSON.parse(data).code == 1) {
              renders();
              ElNotification({
                title: "Success",
                message: "添加成功",
                type: "success"
              });
              dialogFormVisible.value = false;
              loading.value = true;
              setTimeout(() => {
                loading.value = false;
              }, 800);
            } else {
              ElNotification({
                title: "Error",
                message: "操作失败",
                type: "error"
              });
            }
          })
          .catch(error => {
            console.log(error);
          });
        console.log(addobj);
      } else {
        ElNotification({
          title: "Error",
          message: "请完善菜单信息",
          type: "error"
        });
      }
    } else {
      let editobj = {
        id: efitid.value,
        type: form.type,
        name: form.name,
        menus: form.menus.join(',')
      };
      addItem(editobj)
        .then(data => {
          console.log(JSON.parse(data));
          if (JSON.parse(data).code == 1) {
            renders();
            ElNotification({
              title: "Success",
              message: "操作成功",
              type: "success"
            });
            dialogFormVisible.value = false;
            loading.value = true;
            setTimeout(() => {
              loading.value = false;
            }, 800);
          } else {
            ElNotification({
              title: "Error",
              message: "操作失败",
              type: "error"
            });
          }
        })
        .catch(error => {
          console.log(error);
        });
      console.log(editobj);
    }
  });
};

// 加载效果
const loading = ref(false);

// 删除按钮
const delid = ref();
const centerDialogVisible = ref(false);
let delsure = elid => {
  centerDialogVisible.value = true;
  console.log(elid);
  delid.value = elid;
};

// 确认删除
let delyes = () => {
  centerDialogVisible.value = false;
  delItem({ id: delid.value })
    .then(data => {
      console.log(JSON.parse(data));
      if (JSON.parse(data).code == 1) {
        renders();
        ElNotification({
          title: "Success",
          message: "操作成功",
          type: "success"
        });
        loading.value = true;
        setTimeout(() => {
          loading.value = false;
        }, 800);
      } else {
        ElNotification({
          title: "Error",
          message: "操作失败",
          type: "error"
        });
      }
    })
    .catch(error => {
      console.log(error);
    });
};

let searchinp = () => {
  let datas = tableData.value;
  tableData.value = datas.filter(function (item) {
    if (String(item.name).indexOf(String(mneuName.value)) > -1) {
      loading.value = true;
      setTimeout(() => {
        loading.value = false;
      }, 1200);
      return item;
    } else {
      loading.value = true;
      setTimeout(() => {
        loading.value = false;
      }, 1200);
      tableData.value = [];
    }
  });
};

// 弹窗内树形虚拟选择器------------------------------------------------

interface Tree {
  id: number;
  label: string;
  children?: Tree[];
}

const treeRef = ref<InstanceType<typeof ElTree>>();
const defaultProps = {
  children: "children",
  label: "title"
};
// 展开所有
const zhanstatus = ref(0);
let takeall = () => {
  console.log(folderTreeRef.value);
  
  zhanstatus.value++;
  if (zhanstatus.value % 2 == 0) {
    const nodes = folderTreeRef.value.store._getAllNodes();
    nodes.forEach(item => {
      item.expanded = false;
    });
  } else {
    const nodes = folderTreeRef.value.store._getAllNodes();
    nodes.forEach(item => {
      item.expanded = true;
    });
  }
};

// 全选
const checkstatus = ref(0);
let checkall = () => {
  console.log(mneudata.value);

  checkstatus.value++;
  if (checkstatus.value % 2 != 0) {
    folderTreeRef.value.setCheckedNodes(mneudata.value);
  } else {
    folderTreeRef.value.setCheckedNodes([]);
  }
  form.menus = folderTreeRef.value.getCheckedKeys();
  console.log("通过node获取", folderTreeRef.value.getCheckedNodes());
  console.log("通过key获取", folderTreeRef.value.getCheckedKeys());
};

// ----------------------------------------------------------------------------
const currentPage = ref<any>(1);
const pageSize = ref(10);
const small = ref(false);
const background = ref(false);
const disabled = ref(false);
const tableDatalen = ref();
const handleSizeChange = (val: number) => {
  console.log(`${val} items per page`);
};
const handleCurrentChange = (val: number) => {
  console.log(`current page: ${val}`);
};
</script>
<template>
  <div class="pagebg">
    <h1>角色管理</h1>
    <!-- 输入框 -->
    <div class="searchbox">
      <div>
        <el-input
          style="width: 240px; margin-right: 20px"
          v-model="mneuName"
          placeholder="请输入角色名称"
          :suffix-icon="Search"
          @input="searchinp"
        />
        <el-button @click="chongzhi">重置</el-button>
      </div>
      <!-- 新增按钮 -->
      <div>
        <el-button type="primary" @click="addon">新增</el-button>
      </div>
    </div>

    <!-- 表格区域 -->
    <div>
      <el-table
        :data="
          tableData.slice((currentPage - 1) * pageSize, currentPage * pageSize)
        "
        border
        stripe
        style="width: 100%"
        :header-cell-style="{ textAlign: 'center' }"
        :cell-style="{ textAlign: 'center' }"
        v-loading="loading"
        show-overflow-tooltip
      >
        <el-table-column prop="id" label="序号" width="60" />
        <el-table-column prop="name" label="角色名称" width="150" />
        <el-table-column prop="type" label="角色类型" width="130">
          <template v-slot="scope">
            <el-tag class="mx-1" size="large">{{
              scope.row.type == 1
                ? "超管"
                : scope.row.type == 2
                  ? "劳务公司"
                  : scope.row.type == 3
                    ? "项目部"
                    : "审核员"
            }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column
          style="text-wrap: nowrap; text-overflow: ellipsis"
          prop="menus_name"
          label="可访问菜单"
        />
        <el-table-column label="操作" width="160">
          <template v-slot="scope">
            <el-button type="primary" @click="editbox(scope.row.id)"
              >编辑</el-button
            >
            <el-button type="danger" @click="delsure(scope.row.id)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="pageBox">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[10, 20, 30, 50]"
        :small="small"
        :disabled="disabled"
        :background="background"
        layout="total, sizes, prev, pager, next, jumper"
        :total="tableDatalen"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    <!-- 添加、编辑 弹窗 -->

    <el-dialog
      v-model="dialogFormVisible"
      :title="modelTitle"
      style="position: relative"
      :close-on-click-modal="false"
    >
      <el-form :model="form" :rules="rules" ref="ruleFormRef">
        <el-form-item
          label="角色名称"
          :label-width="formLabelWidth"
          prop="name"
        >
          <el-input
            v-model="form.name"
            autocomplete="off"
            placeholder="请选择角色名称"
          />
        </el-form-item>
        <el-form-item
          label="角色类型"
          :label-width="formLabelWidth"
          prop="type"
        >
          <el-select
            v-model="form.type"
            placeholder="请选择角色类型"
            style="width: 100%"
          >
            <el-option label="超级管理员" value="1" />
            <el-option label="劳务公司" value="2" />
            <el-option label="项目部" value="3" />
            <el-option label="审核员" value="4" />
          </el-select>
        </el-form-item>
        <el-form-item label="可选择菜单" :label-width="formLabelWidth">
          <el-tree
            ref="folderTreeRef"
            :data="mneudata"
            show-checkbox
            node-key="id"
            highlight-current
            :props="defaultProps"
          />
        </el-form-item>
      </el-form>
      <div class="btnGroup">
        <el-button @click="takeall" style="height: 24px">{{
          zhanstatus % 2 != 0 ? "收起所有" : "展开所有"
        }}</el-button>
        <el-button @click="checkall" style="height: 24px">{{
          checkstatus % 2 != 0 ? "取消全选" : "全选"
        }}</el-button>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取消</el-button>
          <el-button type="primary" @click="addMneu"> 确认 </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 确认删除弹窗 -->
    <el-dialog v-model="centerDialogVisible" title="Warning" width="30%" center>
      <span> 确定删除 </span>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="centerDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="delyes"> 确认 </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<style>
.grow {
  padding: 0;
}
.pagebg {
  width: auto;
  height: 100%;
  background-color: #ffffff;
}
.searchbox {
  width: auto;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.pageBox {
  width: 100%;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.btnGroup {
  position: absolute;
  top: 190px;
  left: 40%;
}
</style>
